package org.gl.customview.charview;

import com.chanceit.ssss.activity.R;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioManager;
import android.media.SoundPool;
import android.view.MotionEvent;
import android.view.View;

/**
 * 统计图实例
 * 
 * @author Ge Liang
 */
public class LineView extends View {
	private int xPoint = 0;// 原点X坐标
	private int yPoint = 0;// 原点Y坐标
	private int xLengh = 240;// X轴长度
	private int yLengh = 320;// Y轴长度
	private float xScale = 24;// X轴一个刻度长度
	private int yScale = 25;// Y轴一个刻度长度
	private int widthBorder = 40;// 内边缘宽度，为了统计图不靠在屏幕的边缘上，向边缘缩进距离。最好大于30。
	// private int TitleBarHeigth = 38;// 状态栏的高度
	private String[] xLableArray;// X轴标签
	private float[] yLableArray;// Y轴标签
	private int[][] dataArray;// 画折线的数值
	private boolean isSoundEnable = false;
	@Override
	public void setSoundEffectsEnabled(boolean soundEffectsEnabled) {
		super.setSoundEffectsEnabled(soundEffectsEnabled);
		isSoundEnable = true;
	}
	/**
	 * 被选中的详细的点数据数组
	 */
	private DetailPopuWindow[] details;
	private float x_current;
	private float y_current;
	private Paint paint;
	// private float x_lastDown;
	// private float y_lastDown;
	public int defaultLineColor[] = new int[] {
			0xff29a3e6, 0xfff4bb6a, 0xff19c8d9,
			0xff73ca01, 0xff1aadc1, 0xffCCCCCC, };
	private int sound_climb;
	private int last_drawDetal_x = -1;
	// private Path path_line;
	SoundPool sound;

	public LineView(Context context) {
		super(context);
		sound = new SoundPool(10, AudioManager.STREAM_MUSIC, 5);
		sound_climb = sound.load(context, R.raw.knock, 1);
		// int OO = sound.load(this, R.raw.oo , 1);
		mDetailPopuWindow = new DetailPopuWindow();
		mDetailPopuWindow.setShow(true);
		if (getBackground() == null) {
			setBackgroundColor(0xffF1F1F1);
		}
	}

	/**
	 * 实例化值
	 * 
	 * @param screenWidth
	 *            手机屏幕宽度
	 * @param ScreenHeight
	 *            手机屏幕高度
	 * @param xLable
	 *            X轴标签
	 * @param yLable
	 *            Y轴标签
	 * @param dataArray
	 *            统计数据 多维数组 支持多条线. 注意:多维数组的大小必须一致,否则可能出现不可意料的问题
	 */
	public void initValue(int screenWidth, int ScreenHeight, int[]... dataArray) {
		if (dataArray == null || dataArray.length <= 0) {
			return;
		}

		this.dataArray = dataArray;
		xPoint = 0;
		yPoint = 0;

		// 38 是手机状态栏的大概高度，这是i9100上测试的，如果应用有标题栏需要在这个基础上加，差不多两倍吧。
		xPoint += 0 + widthBorder;
		// yPoint = ScreenHeight - widthBorder - TitleBarHeigth;
		yPoint = ScreenHeight - widthBorder;
		xLengh = screenWidth - widthBorder * 2;
		// yLengh = ScreenHeight - widthBorder * 2 - TitleBarHeigth;
		yLengh = ScreenHeight - widthBorder * 2;
		int maxXlength = 0;
		for (int i = 0; i < dataArray.length; i++) {
			maxXlength = dataArray[i].length > maxXlength ? dataArray[i].length
					: maxXlength;
		}

		int dataArrayLength = maxXlength;
		if (dataArrayLength == 0) {
			return;
		}
		// TODO 多条线支持
		// FIXME 0值问题
		// 计算x轴上刻度间隔距离
		xLableArray = new String[dataArrayLength];
		// xScale = ((xLengh / dataArrayLength) > xScale) ? (xLengh /
		// dataArrayLength)
		// : xScale;
		xScale = (xLengh / dataArrayLength);

		int maxY = 0;
		for (int i = 0; i < xLableArray.length; i++) {
			xLableArray[i] = "" + i;// 给X轴上的刻度线添加名称
			for (int j = 0; i < dataArray.length && j < dataArray[i].length; j++) {
				maxY = dataArray[i][j] > maxY ? dataArray[i][j] : maxY;// 计算Y轴最大值
			}
			// maxY = dataArray[i] > maxY ? dataArray[i] : maxY;// 计算Y轴最大值
		}

		// Y轴上的刻度线的数量
		final int ySize = 5;
		// int ySize = (yLengh % yScale == 0) ? (yLengh / yScale)
		// : ((yLengh / yScale) + 1);
		yScale = yLengh / ySize;
		yLableArray = new float[ySize + 1];
		// float offset = Math.round((float)maxY/ySize);//兼容小数点.
		float offset = (float) maxY / ySize;
		for (int i = 0; i < ySize + 1; i++) {
			yLableArray[i] = (i * offset);
		}

		details = new DetailPopuWindow[dataArray.length];
		for (int i = 0; i < dataArray.length; i++) {
			details[i] = new DetailPopuWindow();
		}
		// 设置画笔
		paint = new Paint();

		mDetailPopuWindow.x = xPoint;
		mDetailPopuWindow.show = true;
		last_drawDetal_x = -1;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if (paint == null) {
			return;
		}
		paint.setStrokeWidth(1f);
		paint.setStyle(Paint.Style.STROKE);// 设置画笔样式
		paint.setAntiAlias(true);// 去锯齿
		paint.setColor(Color.BLACK);// 设置颜色
		paint.setTextSize(12);// 设置字体
//		// 画X轴轴线
//		canvas.drawLine(xPoint, yPoint, xPoint + xLengh + xScale, yPoint, paint);
//		// 画X轴箭头
//		canvas.drawLine(xPoint + xScale + xLengh - 6, yPoint - 3, xPoint
//				+ xLengh + xScale, yPoint, paint);
//		canvas.drawLine(xPoint + xScale + xLengh - 6, yPoint + 3, xPoint
//				+ xLengh + xScale, yPoint, paint);// TODO 补充所有的线
//		// 画Y轴轴线
//		canvas.drawLine(xPoint, yPoint, xPoint, yPoint - yLengh - 24, paint);
//		// 画Y轴箭头
//		canvas.drawLine(xPoint + 3, yPoint - yLengh - 18, xPoint, yPoint
//				- yLengh - 24, paint);
//		canvas.drawLine(xPoint - 3, yPoint - yLengh - 18, xPoint, yPoint
//				- yLengh - 24, paint);

		paint.setColor(Color.GRAY);// 设置颜色
		paint.setStrokeWidth(1f);
		
//		{// 画X轴刻度
//			canvas.drawLine(xPoint + xScale * (dataArray.length), yPoint - 3,
//					xPoint + xScale * (dataArray.length), yPoint, paint);
//			// 画X轴刻度标签
//			canvas.drawText("--", xPoint + xScale * (dataArray.length),
//					yPoint + 15, paint);
//		}

		for (int i = 0; yLableArray != null && i < yLableArray.length; i++) {
			paint.setColor(Color.GRAY);// 设置颜色
			paint.setStrokeWidth(1f);
			// 画Y轴刻度
			canvas.drawLine(xPoint, yPoint - yScale * i, xPoint + 3, yPoint
					- yScale * i, paint);
			// 画Y轴刻度标签

			canvas.drawText(
					(yLableArray[i] > 10 && String.valueOf(yLableArray[i])
							.length() > 2) ? String.format("%.0f",
							yLableArray[i]) : String.format("%.2f",
							yLableArray[i]), xPoint - 30, yPoint - yScale * i
							+ 3, paint);

			paint.setStrokeWidth(0.5f);
			canvas.drawLine(xPoint, yPoint - yScale * i, xPoint + xLengh,
					yPoint - yScale * i, paint);
			paint.setColor(0xffe3e3e3);// 设置颜色

			if (i != 0) {
				for (int j = 1; j < 4; j++) {
					// 画Y轴刻度线
					canvas.drawLine(xPoint, yPoint - yScale * i + yScale / 4
							* j, xPoint + xLengh, yPoint - yScale * i + yScale
							/ 4 * j, paint);
				}

			}

		}
		for (int i = 0; i < dataArray.length; i++) {
			paint.setColor((i > defaultLineColor.length - 1 ? 0xffff0000
					: defaultLineColor[i]));// 设置颜色
			paint.setStrokeWidth(2f);
			drawDataLine(canvas, dataArray[i]);
		}

		drawDetailPopuWindow(canvas);
	}

	/**
	 * 画统计图上的数据点连接折线
	 * 
	 * @param canvas
	 * @param lineDataArray
	 *            数据线的点
	 */
	private void drawDataLine(Canvas canvas, int[] lineDataArray) {
		int i = 0;
		for (i = 0; lineDataArray != null && i < lineDataArray.length; i++) {
			// paint.setColor(Color.GRAY);// 设置颜色
			// paint.setStrokeWidth(1f);
			// if (i != 0 && i % yLableArray.length == 0) {
			// // 画X轴刻度
			// canvas.drawLine(xPoint + xScale * i, yPoint - 3, xPoint
			// + xScale * i, yPoint, paint);
			// // 画X轴刻度标签
			// canvas.drawText(xLableArray[i], xPoint + xScale * i,
			// yPoint + 15, paint);
			// }

			// if (lineDataArray != null && lineDataArray.length > 0
			// && i < lineDataArray.length) {

			int ydata = getYDataPoint(lineDataArray[i]);
			if (ydata != 0) {
				canvas.drawCircle(xPoint + xScale * i, ydata, 2, paint);
				if (lineDataArray.length > i + 1) {
					canvas.drawLine(xPoint + xScale * i,
							getYDataPoint(lineDataArray[i]), xPoint + xScale
									* (i + 1),
							getYDataPoint(lineDataArray[i + 1]), paint);
				}
			}

			// }
		}
	}

	/**
	 * 画某个点上的纤细内容.
	 * 
	 * @param canvas
	 */
	private void drawDetailPopuWindow(Canvas canvas) {
		if (monShowDetailInfo != null && mDetailPopuWindow.isShow()) {// 如果有显示详细信息的接口对接到这里,则画外部视图
			if (mDetailPopuWindow.x < xPoint
					|| mDetailPopuWindow.x >= xPoint + xLengh) {// 限制边界
				return;
			}

			paint.setColor(Color.argb(255, 18, 158, 204));// 设置颜色

			paint.setStrokeWidth(2f);
			// 画指示线
			canvas.drawLine(mDetailPopuWindow.x, yPoint + 18,
					mDetailPopuWindow.x, yPoint - yLengh - 18, paint);
			paint.setStrokeWidth(1f);
			if (last_drawDetal_x != mDetailPopuWindow.index) {// 查看的点发生了变化
				if (isSoundEnable) {
					sound.play(sound_climb, 1, 1, 0, 0, 1);
				}
				// 绘制的任务交给外部接口
				for (int i = 0; i < details.length; i++) {
					if (mDetailPopuWindow.index < dataArray[i].length) {
						details[i].content = dataArray[i][mDetailPopuWindow.index]
								+ "";
					} else {
						details[i].content = "out of array range";
					}
					details[i].title = mDetailPopuWindow.title;
					mDetailPopuWindow.index = mDetailPopuWindow.index > xLableArray.length - 1 ? xLableArray.length - 1
							: mDetailPopuWindow.index;
					details[i].index = mDetailPopuWindow.index;
				}
				monShowDetailInfo.showDetailInfo(details);
			}
			last_drawDetal_x = mDetailPopuWindow.index;
			return;
		}
		if (mDetailPopuWindow.isShow()) {
			int y = mDetailPopuWindow.y;
			int x = mDetailPopuWindow.x;
			paint.setTextSize(32);

			canvas.drawText(mDetailPopuWindow.getTitle() + "",
					mDetailPopuWindow.x, y, paint);
			canvas.drawText(xLengh + "", xLengh, y + 18, paint);
			double random = Math.random();
			paint.setAlpha((int) (255 * (1 - random)));
			paint.setStrokeWidth((float) Math.random() * 10);
			paint.setStyle(Paint.Style.FILL_AND_STROKE);
			canvas.drawCircle(mDetailPopuWindow.x, y,
					(float) ((int) 20 * random), paint);
			paint.setAlpha(255);

			paint.setStrokeWidth(1f);

			paint.setColor(Color.argb(255, 161, 199, 57));// 设置颜色
			paint.setTextSize(48);
			if (x + 20 > yLengh) {
				x -= 20;
				x -= paint.measureText(mDetailPopuWindow.getContent());
				y -= 40;
			}
			canvas.drawText(mDetailPopuWindow.getContent() + "", x + 20,
					y + 18, paint);
			paint.setColor(Color.argb(255, 18, 158, 204));// 设置颜色

			paint.setStrokeWidth(2f);
			// 画指示线 FIXME 这里仅仅显示第一条的详细信息
			canvas.drawLine(mDetailPopuWindow.x, mDetailPopuWindow.y, xPoint
					+ xScale * (mDetailPopuWindow.index),
					getYDataPoint(dataArray[0][mDetailPopuWindow.index]), paint);
			paint.setStrokeWidth(1f);

			if (last_drawDetal_x != mDetailPopuWindow.index) {// 查看的点发生了X轴位置变化
				sound.play(sound_climb, 1, 1, 0, 0, 1);
			}
			last_drawDetal_x = mDetailPopuWindow.index;
		}
	}

	public void setOnShowDetailInfo(onShowDetailInfo monShowDetailInfo) {
		this.monShowDetailInfo = monShowDetailInfo;
	}

	// /**
	// * 得到每一等分的长度
	// *
	// * @param num
	// * 所要分成的等份
	// * @param length
	// * 要分割的总长度
	// * @return
	// */
	// private int getScale(int num, int length) {
	// if (num > 0 && length > 0) {
	// length -= 10;// 为了美观，缩进
	// length = length - (length % num);
	// return length / num;
	// } else {
	// return 0;
	// }
	//
	// }

	/**
	 * 得到点的Y屏幕绘制坐标
	 * 
	 * @param data
	 *            Y点的数据值
	 * @return
	 */
	private int getYDataPoint(int data) {
		int y = (int) (yPoint - (((float) data / (float) yLableArray[yLableArray.length - 1]) * yLengh));
		// double yScale_db = (double) yScale;
		// double pxSize = yScale_db / yLableArray[1];
		// int pxSize_int = (int) pxSize;
		// int last = 0;
		// if ((last = data % yLableArray[1]) == 0) {
		// y = yPoint - (data / yLableArray[1] * yScale);
		// } else {
		// y = yPoint - (data / yLableArray[1] * yScale) - pxSize_int * last;
		// }

		return y;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		try {
			x_current = event.getX();
			y_current = event.getY();
			switch (event.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:
				mDetailPopuWindow.setShow(true);
				// x_lastDown = event.getX();
				// y_lastDown = event.getY();
				break;
			case MotionEvent.ACTION_POINTER_DOWN:
				break;
			case MotionEvent.ACTION_MOVE:
				mDetailPopuWindow.x = (int) x_current;
				mDetailPopuWindow.y = (int) y_current - yLengh / 2;
				try {
					mDetailPopuWindow.setTitle(""
							+ xLableArray[getIndexFromDataArray(x_current,
									y_current)]);
					mDetailPopuWindow.setContent(""
							+ dataArray[0][getIndexFromDataArray(x_current,
									y_current)]);
				} catch (Exception e) {// TODO 处理多跟线对应的数组数据长度不一致的问题
					e.printStackTrace();
					mDetailPopuWindow.setTitle("");
				}

				mDetailPopuWindow.index = getIndexFromDataArray(x_current,
						y_current);
				invalidate();
				break;
			case MotionEvent.ACTION_UP:
				// if (x_current>xLengh) {
				// scrollBy(20, 0);
				// }else if(x_current<xPoint){
				// scrollBy(-20, 0);
				// } // 支持滑动
			case MotionEvent.ACTION_OUTSIDE:
			default:
				mDetailPopuWindow.setShow(false);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return true;
		}

	}

	private int getIndexFromDataArray(float x_current2, float y_current2) {
		if (dataArray == null || (x_current2 - xPoint) <= 0) {
			return 0;
		}
		int index = (int) ((x_current2 - xPoint) / xScale);
		// System.out.println("getIndexFromDataArray:" + index);
		// index = (index > dataArray.length - 1) ? dataArray.length - 1 :
		// index;
		return index;
	}

	DetailPopuWindow mDetailPopuWindow;

	/**
	 * 点的详细的数据
	 * 
	 * @author Administrator
	 * 
	 */
	public class DetailPopuWindow {
		/**
		 * 在数据数组中的位置 通过它找到具体的value.
		 */
		public int index;
		/**
		 * 内容 一般为X轴坐标.
		 */
		public String title ="";
		/**
		 * 标题 一般为点的value
		 */
		public String content = "0";

		/**
		 * 标题
		 * 
		 * @return
		 */
		public String getTitle() {
			return title;
		}

		public void setTitle(String title) {
			this.title = title;
		}

		public String getContent() {
			return content;
		}

		public void setContent(String content) {
			this.content = content;
		}

		public boolean isShow() {
			return show;
		}

		public void setShow(boolean show) {
			this.show = show;
		}

		int x;
		int y;
		boolean show;
	}

	onShowDetailInfo monShowDetailInfo;

	/**
	 * 对外输出选中的点的详细数据接口
	 * 
	 * @author Administrator
	 * 
	 */
	public interface onShowDetailInfo {
		public void showDetailInfo(final DetailPopuWindow... mDetailPopuWindow);
	};
}